{*******************************************************************************
 *                                                                             *
 *          Mathengine                                                         *
 *                                                                             *
 *          (C)Copyright Jimx 2011                                             *
 *                                                                             *
 *          http://math-engine.googlecode.com                                  *
 *                                                                             *
 *******************************************************************************
 *  This file is part of Mathengine.                                           *
 *                                                                             *
 *  Mathengine is free software:                                               *
 *  you can redistribute it and/or modify                                      *
 *  it under the terms of the GNU General Public License as published by       *
 *  the Free Software Foundation, either version 3 of the License, or          *
 *  (at your option) any later version.                                        *
 *                                                                             *
 *  Mathengine is distributed                                                  *
 *  in the hope that it will be useful,                                        *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of             *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
 *  GNU General Public License for more details.                               *
 *                                                                             *
 *  You should have received a copy of the GNU General Public License          *
 *  along with Mathengine.                                                     *
 *  If not, see <http://www.gnu.org/licenses/>.                                *
 *******************************************************************************}
 unit math.mathengine;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, iniFiles, sci.types,
  sci.log, sci.config, math.config,
  math.global, math.category;

type
  TMainForm = class(TForm)
    memoInput: TMemo;
    comboSubcate: TComboBox;
    gbInput: TGroupBox;
    btnCalculate: TButton;
    gbOutput: TGroupBox;
    memoOutput: TMemo;
    detail: TMemo;
    comboCategories: TComboBox;
    procedure btnCalculateClick(Sender: TObject);
    procedure comboSubcateChange(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure comboCategoriesChange(Sender: TObject);
  private
    { Private declarations }
    fHeight, fWidth: integer;
    curcate, cursubcate: integer;
  public
    { Public declarations }
    line: integer;
    langFile: TIniFile;
    procedure outMsg(msg: string);
    procedure languageInit;
  end;

var
  MainForm: TMainForm;

implementation

{$R *.dfm}

procedure TMainForm.btnCalculateClick(Sender: TObject);
var
  expression: string;
  tmp: PChar;
  inp, retval: TData;
begin
  memoOutput.Lines.Clear;
  detail.Lines.Clear;
  line := -1;
  while line < memoInput.Lines.Count - 1 do
  begin
    inc(line);
    expression := memoInput.Lines[line];
    memoOutput.Lines.Add('Input[' + inttostr(line) + '] := ' + expression);
    try
      inp.input := PChar(expression);
      retval := categories[curcate].subcates[cursubcate].func(inp);
      memoOutput.Lines.Add('Output[' + inttostr(line) + '] = ' + retval.output.ValueFromIndex[0]);
    except
      outMsg(' Error: Illegal formula');
    end;
  end;
end;

procedure TMainForm.comboCategoriesChange(Sender: TObject);
var
  i: integer;
begin
  if comboCategories.ItemIndex = -1 then curcate := 0
  else curcate := comboCategories.ItemIndex;
  cursubcate := 0;

  comboSubcate.Clear;
  comboSubcate.Text := categories[curcate].subcates[0].caption;
  btnCalculate.Caption := categories[curcate].subcates[0].btncaption;
  for i := 0 to categories[curcate].nrsub do
    comboSubcate.Items.Add(categories[curcate].subcates[i].caption);
end;

procedure TMainForm.comboSubcateChange(Sender: TObject);
begin
  if comboSubcate.ItemIndex = -1 then cursubcate := 0
  else cursubcate := comboSubcate.ItemIndex;

  btnCalculate.Caption := categories[curcate].subcates[cursubcate].btncaption;
end;

procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  closefiles(mathLog);
end;

procedure TMainForm.FormCreate(Sender: TObject);
var
  i: integer;
begin
  dbginit(ExtractFilePath(ParamStr(0)) + 'log\math_debug.dbg');
  loginit(mathLog, ExtractFilePath(ParamStr(0)) + 'log\math_log.log');
  fHeight := Self.Height;
  fWidth := Self.Width;
  config_init;
  languageInit;
  module_init;
  category_init(langfile);

  comboCategories.Text := categories[0].name;
  comboSubcate.Text := categories[0].subcates[0].caption;
  btnCalculate.Caption := categories[0].subcates[0].btncaption;
  for i := 0 to mathConf.nrCategories - 1  do
    comboCategories.Items.Add(categories[i].name);
  for i := 0 to categories[0].nrsub do
    comboSubcate.Items.Add(categories[0].subcates[i].caption);
  curcate := 0;
  curcate := 0;
end;

procedure TMainForm.FormResize(Sender: TObject);
var
  i: integer;
begin
  for i := 0 to Self.ComponentCount - 1 do
  begin
    TEdit(Self.Components[i]).ScaleBy(width, fwidth);
    TEdit(Self.Components[i]).Top := Round(TEdit(Self.Components[i]).Top * (height / fheight));
    TEdit(Self.Components[i]).Left := Round(TEdit(Self.Components[i]).Left * (width / fwidth));
  end;
  fheight := height;
  fwidth := width;
end;

(***************************************
 *             outMsg                  *
 ***************************************
 *  Output a message.                  *
 ***************************************)
procedure TMainForm.outMsg(msg: string);
begin
  memoOutput.Lines.Add('Output: ' + msg);
end;

(***************************************
 *           languageInit              *
 ***************************************
 *  Initialize multi-language.         *
 ***************************************)
procedure TMainForm.languageInit;
var
  filename: string;
  i: integer;
  buf: array [0..30] of char;
  lang: string;
begin
  log(mathLog, 'Initializing language...');
  GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SENGLANGUAGE, buf, 29);
  lang := string(buf);
  filename := ExtractFilePath(Paramstr(0))+'language\' + lang + '.ini';
  if FileExists(filename) then
  begin
    try
      langFile := TIniFile.Create(filename);
    except
      showMessage('Can not open language file, terminate.');
      halt;
    end;
  end
  else
  begin
    try
      langFile := TIniFile.Create(ExtractFilePath(Paramstr(0))+'language\English.ini');
    except
      showMessage('Can not open language file, terminate.');
      halt;
    end;
  end;

  gbInput.Caption := langFile.ReadString('GroupBox', 'gbInput', 'Input');
  gbOutput.Caption := langFile.ReadString('GroupBox', 'gbOutput', 'Output');

  btnCalculate.Caption := langFile.ReadString('Button', 'caption0', '');
  for i := 0 to comboSubcate.items.Count - 1 do
    comboSubcate.items[i] := langFile.ReadString('Mode', 'Mode' + intToStr(i), '');
  comboSubcate.Text := langFile.ReadString('Mode', 'Mode0', '');
end;

end.
